package com.example.braden.answergame.modules.main;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import butterknife.BindView;

import com.example.braden.answergame.R;
import com.example.braden.answergame.base.BaseActivity;
import com.example.braden.answergame.base.BaseResult;
import com.example.braden.answergame.common.Constant;
import com.example.braden.answergame.common.LogUtils;
import com.example.braden.answergame.common.im.IMUtil;
import com.example.braden.answergame.common.utils.MediaUtil;
import com.example.braden.answergame.common.utils.ToastUtil;
import com.example.braden.answergame.common.view.AnswerCardLayout;
import com.example.braden.answergame.common.view.BackDialog;
import com.example.braden.answergame.common.view.BubblePopupWindow;
import com.example.braden.answergame.common.view.PropView;
import com.example.braden.answergame.common.view.ResultDialog;
import com.example.braden.answergame.common.view.RuleDialog;
import com.example.braden.answergame.component.CardDisplayManager;
import com.example.braden.answergame.modules.main.domain.GameOverEntity;
import com.example.braden.answergame.modules.main.domain.PropMessageEntity;
import com.example.braden.answergame.modules.main.domain.ReadyEntity;
import com.example.braden.answergame.modules.main.domain.UsePropEntity;
import com.example.braden.answergame.modules.main.domain.UserPropInfo;
import com.example.braden.answergame.modules.main.presenter.MainContact;
import com.example.braden.answergame.modules.main.presenter.MainPresenter;
import com.tencent.imsdk.TIMCallBack;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by braden on 2018/3/1.
 */
public class MainActivity extends BaseActivity implements View.OnClickListener, MainContact.IView {

    @BindView(R.id.iv_back)
    ImageView ivBack;
    @BindView(R.id.iv_center_img)
    ImageView ivCenterImg;
    @BindView(R.id.iv_rule)
    ImageView ivRule;
    @BindView(R.id.answer_layout)
    AnswerCardLayout answerLayout;
    @BindView(R.id.prop_1)
    PropView prop1;
    @BindView(R.id.prop_2)
    PropView prop2;
    @BindView(R.id.prop_3)
    PropView prop3;
    @BindView(R.id.top_layout)
    RelativeLayout topLayout;
    @BindView(R.id.ll_bottom_layout)
    LinearLayout llBottomLayout;
    @BindView(R.id.id_imageView)
    ImageView idImageView;
    @BindView(R.id.id_loading_view)
    FrameLayout idLoadingView;
    @BindView(R.id.btn_again)
    Button btnAgain;
    @BindView(R.id.ll_net_wrong)
    LinearLayout llNetWrong;
    private List<PropView> propViews;
    private CardDisplayManager cardDisplayManager;//答题卡的逻辑控制类
    //逻辑控制类中的回调接口，用来更新界面UI
    private MainPresenter mainPresenter;//界面逻辑处理P层
    private static UserPropInfo userPropInfo;//用户信息和道具信息
    private Prop propStatus;//用户操作道具标志
    private static final String fuhuoka = "datifuhuo";
    private static final String yanshika = "datishengming";
    private static final String paichuka = "datixuanxiang";
    private UserPropInfo.BodyBean.PropsBean fuhuokaBean, yanshikaBean, paichukaBean;
    @NonNull
    private BubblePopupWindow reviveBubble;
    public static int netIsWrong;

    //=-1表示ready开始请求=1表示ready请求失败，-2表示开始登录IM，=2表示IM登录失败，-3表示start开始请求，=3表示start失败
    enum Prop {
        REVIVE, REMOVE, DELAY, NULL
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getIntentData();
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//强制竖屏
        reviveBubble = null;
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    protected int layoutId() {
        return R.layout.activity_main;
    }

    /**
     * 获取游戏平台传过来的OPENID和ROOMID
     */
    private void getIntentData() {
        Constant.OPENID = getIntent().getStringExtra("openId");
        Constant.ROOMID = getIntent().getStringExtra("roomId");
//        LogUtils.e("ROOMID:" + Constant.ROOMID);
        String base_ip = getIntent().getStringExtra("server_ip");
        if (Constant.OPENID == null || Constant.ROOMID == null) {
            finishActy(Constant.FINISH_ACTIVE);
            return;
        }
        if (base_ip != null && !base_ip.equals("")) {
            Constant.setBaseUrl(base_ip);
        }
        initView();
        LogUtils.e("openid:" + Constant.OPENID + "---正式版本versonName:2.1.0");
    }

    /**
     * 初始化控件，开始倒计时和ready请求
     */
    private void initView() {
        mainPresenter = new MainPresenter(this, this);
        //answerLayout.setNetWorkCallback(this);
        CardDisplayManager.CardDisplayLogicCallback cardDisplayLogicCallback = new
                CardDisplayLoginCallbackImpl();
        cardDisplayManager = new CardDisplayManager(this, cardDisplayLogicCallback, answerLayout);
        propViews = new ArrayList<>();
        propViews.add(prop1);
        propViews.add(prop2);
        propViews.add(prop3);
        prop1.setOnClickListener(this);
        prop2.setOnClickListener(this);
        prop3.setOnClickListener(this);
        ivBack.setOnClickListener(this);
        ivRule.setOnClickListener(this);
        btnAgain.setOnClickListener(this);
        //开始倒计时
        //answerLayout.startReadyCountDown();
        //请求ready接口
        mainPresenter.requestReadyGame();
        AnimationDrawable anim = (AnimationDrawable) idImageView.getDrawable();
        anim.start();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.prop_1://复活卡，之后再答错题之后才能点击使用倒计时提示倒计时五秒钟才能使用
                if (!cardDisplayManager.getIsCanRevive()) {
                    ToastUtil.showShort(getString(R.string.dont_use_revive_1));
                    return;
                } else if (fuhuokaBean == null || fuhuokaBean.getGame_count() < 1) {
                    ToastUtil.showShort(getString(R.string.dont_use_revive_2));
                    return;
                } else if (fuhuokaBean.getCount() < 1) {
                    LogUtils.e("fuhuoka:" + fuhuokaBean.getCount());
                    ToastUtil.showShort(getString(R.string.prop_not_enough));
                    return;
                }
                propStatus = Prop.REVIVE;
                if (reviveBubble != null) {
                    reviveBubble.cancle();
                }
                MediaUtil.getInstance(MainActivity.this).playeSmallVoice(R.raw.use_resurgence);
                mainPresenter.requestUseProp(answerLayout.getQid(), fuhuokaBean.getKey(), 1);
                answerLayout.reviveSelf();
                setPropCount(fuhuokaBean, 0);
                break;
            case R.id.prop_2://排除卡，只有在答题倒计时10秒钟之内才能使用
                //首先判断道具数量，再判断当前时间是否可以使用该道具
                if (!cardDisplayManager.getIsCanRemove()) {
                    ToastUtil.showShort(getString(R.string.dont_use_paichu_1));
                    return;
                } else if (paichukaBean == null || paichukaBean.getGame_count() < 1) {
                    ToastUtil.showShort(getString(R.string.dont_use_paichu_2));
                    return;
                } else if (paichukaBean.getCount() < 1) {
                    ToastUtil.showShort(getString(R.string.prop_not_enough));
                    return;
                }
                prop2.setClickable(false);
                propStatus = Prop.REMOVE;
                MediaUtil.getInstance(MainActivity.this).playeSmallVoice(R.raw.use_resurgence);
                mainPresenter.requestUseProp(answerLayout.getQid(), paichukaBean.getKey(), 1);
                answerLayout.useRemoveCard();
                setPropCount(paichukaBean, 1);
                break;
            case R.id.prop_3://延时卡，只有在答题倒计时10秒钟之内才能使用
                if (!cardDisplayManager.isCanUseDelay()) {
                    ToastUtil.showShort(getString(R.string.dont_use_yanshi_1));
                    return;
                } else if (yanshikaBean == null || yanshikaBean.getGame_count() < 1) {
                    ToastUtil.showShort(getString(R.string.dont_use_yanshi_1));
                    return;
                } else if (yanshikaBean.getCount() < 1) {
                    ToastUtil.showShort(getString(R.string.prop_not_enough));
                    return;
                }
                prop3.setClickable(false);
                propStatus = Prop.DELAY;
                answerLayout.setFirstShowYanshi(false);
                MediaUtil.getInstance(MainActivity.this).playeSmallVoice(R.raw.use_resurgence);
                mainPresenter.requestUseProp(answerLayout.getQid(), yanshikaBean.getKey(), 1);
                answerLayout.useDelayCard();
                setPropCount(yanshikaBean, 2);
                break;
            case R.id.iv_back:
                showBackDialog();
                break;
            case R.id.iv_rule:
                RuleDialog.getInstance(MainActivity.this).showDialog();
                break;
            case R.id.btn_again:
                clickAgain();
                break;
        }
    }

    /**
     * 准备开始游戏的回调
     */
    @Override
    public void onReadyGame(boolean success, ReadyEntity data, String errMsg) {
        requestFailOrSuccess(success);
        if (success) {
            if (data != null) {
                ReadyEntity readyEntity = data;
                Constant.IDENTIFIER = readyEntity.getData().getTim_username();
                Constant.USERSIGN = readyEntity.getData().getTim_usersig();
                LogUtils.e("sign:" + Constant.IDENTIFIER + "-----usersing:" + Constant.USERSIGN);
                //登录IM
                netIsWrong = -2;
                IMUtil.getInstance().init(this, loginListener);
                IMUtil.getInstance().login(Constant.IDENTIFIER, Constant.USERSIGN);
            }
        } else {
            netIsWrong = 1;
            ToastUtil.showShort(errMsg);
            if (data.getCode() == -3003) {//房间不存在，关闭游戏
                ToastUtil.showShort("游戏出现异常，即将退出！");
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        finishActy(Constant.FINISH_EXCEPTION);
                    }
                }, 2000);
            }
        }
    }

    private void requestFailOrSuccess(boolean isSuccess) {
        if (isSuccess) {
            llNetWrong.setVisibility(View.GONE);
            idLoadingView.setVisibility(View.VISIBLE);
        } else {
            llNetWrong.setVisibility(View.VISIBLE);
            idLoadingView.setVisibility(View.GONE);
        }
    }

    /**
     * 登录的回调
     */
    private TIMCallBack loginListener = new TIMCallBack() {
        @Override
        public void onError(int i, String s) {
            LogUtils.e("登录失败：" + s);
            //ToastUtil.showShort("登录失败");
            netIsWrong = 2;
            requestFailOrSuccess(false);

        }

        @Override
        public void onSuccess() {
            LogUtils.e("登录成功：");
//            requestFailOrSuccess(true);
            netIsWrong = -2;
            //登录成功之后上报后台
            mainPresenter.requestStatGame();
        }
    };

    /**
     * 开始游戏的回调
     */
    @Override
    public void onStartGame(boolean success, BaseResult data, String errMsg) {
//        LoadingDialog.getInstance(this).dismissDialog();
        requestFailOrSuccess(success);
        if (success) {
            LogUtils.e("开始游戏");
            netIsWrong = 0;
            if (data.getCode() == -3003) {//房间不存在，关闭游戏
                ToastUtil.showShort("游戏出现异常，即将退出！");
                new Handler().postDelayed(() -> finishActy(Constant.FINISH_EXCEPTION), 2000);
            }
        } else {
            netIsWrong = 3;
            LogUtils.e("开始游戏失败：" + errMsg);
            if (data.getCode() == -3004) {
                finishActy(Constant.FINISH_NORMAL);
            }
        }
    }

    /**
     * 使用道具-回调
     */
    @Override
    public void onUseProp(boolean success, UsePropEntity data, String errMsg) {
        prop1.setClickable(true);
        prop2.setClickable(true);
        prop3.setClickable(true);
        if (success) {
            //先判断是否使用了道具，如果没有使用道具（也就是上报作为一个通知），则不更新UI，否则需要更新UI
            if (data.getData().getIs_use() == 0) return;
            switch (propStatus) {
                case REVIVE:
                    ToastUtil.showShort(getString(R.string.revive_success));
                    propStatus = Prop.NULL;
//                  selfIsRight = true;
                    //answerLayout.reviveSelf();
                    //setPropCount(fuhuokaBean, 0);
                    break;
                case REMOVE:
                    ToastUtil.showShort(getString(R.string.paichu_success));
                    //answerLayout.useRemoveCard();
                    //setPropCount(paichukaBean, 1);
                    break;
                case DELAY:
                    ToastUtil.showShort(getString(R.string.yanshi_success));
                    //answerLayout.useDelayCard();
                    //setPropCount(yanshikaBean, 2);
                    break;
            }
        } else {
            ToastUtil.showShort(errMsg);
            //使用道具失败
            if (propStatus == Prop.REVIVE) {
                //如果是使用复活卡失败，则上报道具id=0，is_use=0（默认为输）
                propStatus = Prop.NULL;
                mainPresenter.requestUseProp(answerLayout.getQid(), "0", 0);
            } else {
                ToastUtil.showShort(errMsg);
            }
        }
    }

    /**
     * 答题后上报的回调
     */
    @Override
    public void onAnswerQuestion(boolean success, BaseResult data, String errMsg) {
        if (success) {
            LogUtils.e("上报游戏开始");
        } else {
            /**
             * 如果上报失败为做处理
             */
            LogUtils.e("上报游戏失败");
        }
    }

    /**
     * 退出房间
     */
    @Override
    public void onQuitGame(boolean success, BaseResult data, String errMsg) {
        finishActy(Constant.FINISH_ACTIVE);
    }

    /**
     * 收到问题，更新UI界面
     */
    private void showGameLayout() {
        idLoadingView.setVisibility(View.GONE);
        topLayout.setVisibility(View.VISIBLE);
        answerLayout.setVisibility(View.VISIBLE);
        llBottomLayout.setVisibility(View.VISIBLE);
        llNetWrong.setVisibility(View.GONE);
    }

    /**
     * 设置界面数据
     */
    private void setViewData() {
        if (userPropInfo == null) return;
        answerLayout.setAvatarVivible();
        for (int i = 0; i < userPropInfo.getBody().getUsers().size(); i++) {
            LogUtils.e("faceImg:"+userPropInfo.getBody().getUsers().get(i).getFace_img());
            if (userPropInfo.getBody().getUsers().get(i).getOpen_id().equals(Constant.OPENID)) {
                answerLayout.setLeftIcon(userPropInfo.getBody().getUsers().get(i).getFace_img());
            } else {
                answerLayout.setRightIcon(userPropInfo.getBody().getUsers().get(i).getFace_img());
            }
        }
        for (int i = 0; i < userPropInfo.getBody().getProps().size(); i++) {
            String key = userPropInfo.getBody().getProps().get(i).getKey();
            UserPropInfo.BodyBean.PropsBean bean = userPropInfo.getBody().getProps().get(i);
            if (fuhuoka.equals(key)) {
                fuhuokaBean = bean;
                propViews.get(0).setPropView(bean);
                propViews.get(0).setNumVisible();
            } else if (paichuka.equals(key)) {
                paichukaBean = bean;
                AnswerCardLayout.paichuUrl = bean.getIcon();
                propViews.get(1).setNumVisible();
                propViews.get(1).setPropView(bean);
            } else if (yanshika.equals(key)) {
                yanshikaBean = bean;
                propViews.get(2).setNumVisible();
                propViews.get(2).setPropView(bean);
            }
        }
    }

    /**
     * 当使用过道具后，更新道具数量
     */
    private void setPropCount(UserPropInfo.BodyBean.PropsBean bean, int pos) {
        bean.setCount(bean.getCount() - 1);
        bean.setGame_count(bean.getGame_count() - 1);
        propViews.get(pos).setPropView(bean);
    }

    /**
     * 更新UI的回调
     */
    private class CardDisplayLoginCallbackImpl
            implements CardDisplayManager.CardDisplayLogicCallback {
        @Override
        public void uploadAnswer(int qid, int answerId) {
            mainPresenter.requestUploadChoose(qid, answerId);
        }

        /**
         * 接着发送下一题，更新头像显示
         */
        @Override
        public void nextQuestion(int postion) {
            if (userPropInfo == null) return;
            propStatus = Prop.NULL;
            for (int i = 0; i < userPropInfo.getBody().getUsers().size(); i++) {
                if (userPropInfo.getBody().getUsers().get(i).getOpen_id().equals(Constant.OPENID)) {
                    answerLayout.setLeftIcon(
                            userPropInfo.getBody().getUsers().get(i).getFace_img());
                } else {
                    answerLayout.setRightIcon(
                            userPropInfo.getBody().getUsers().get(i).getFace_img());
                }
            }
            LogUtils.e("nextQuestion:" + postion);
//            if (postion == 1) {
            showGameLayout();
//            }
        }

        /**
         * 自己回答错误
         */
        @Override
        public void answerWrong() {
            LogUtils.e("答题错误");
//            selfIsRight = false;
            if (fuhuokaBean != null && fuhuokaBean.getCount() > 0
                    && fuhuokaBean.getGame_count() > 0) {
                reviveBubble = new BubblePopupWindow(MainActivity.this, cardDisplayManager);
                reviveBubble.showPopup(prop1);
            } else {
                //上报
                mainPresenter.requestUseProp(answerLayout.getQid(), "0", 0);
            }
        }

        /**
         * 收到使用道具消息
         */
        @Override
        public void onReceivePropMessage(PropMessageEntity entity) {
            if (entity.getBody().getProp_key().equals(fuhuokaBean.getKey())) {//复活卡
                if (!entity.getBody().getUser().equals(Constant.OPENID)) {
                    //对手使用了复活卡
                    answerLayout.reviveRight();
//                    isOtherRevive = true;
                }
            } else if (entity.getBody().getProp_key().equals(yanshikaBean.getKey())) {//延时卡
                LogUtils.e("延时卡-self:" + Constant.OPENID + "------otherOpenid:" + entity.getBody()
                        .getUser());
                if (!Constant.OPENID.equals(entity.getBody().getUser())) {
                    answerLayout.setOtherIsUseYanshi(true);
                    LogUtils.e("答题倒计时结束：onReceivePropMessage" + answerLayout.getCountdownIsOver());
                    //收到对方使用延时卡,如果倒计时走完则显示，道具提示
                    if (answerLayout.getCountdownIsOver()) {
                        answerLayout.otherUseYanshi(Constant.YANSHI);
                    }
                }
            }
        }

        /**
         * 未使用道具上报
         */
        @Override
        public void propOver() {
            if (propStatus != Prop.REVIVE) {//如果道具上报的时候，正在使用复活卡，则不立马上报
                mainPresenter.requestUseProp(answerLayout.getQid(), "0", 0);
            }
        }

        /**
         * 游戏结束
         */
        @Override
        public void gameOver(GameOverEntity entity) {
            //只有当下发过问题消息才去显示对错状态，如果发送结束消息的时候还没有发题则是不正常结束
            if (cardDisplayManager.getQuestionEntity() != null) {
                if (entity.getBody().getWinner().equals(Constant.OPENID)) {//赢了
                    ResultDialog.getInstance(MainActivity.this)
                            .showResult(getString(R.string.other_wrong), R.mipmap.win_face);
                } else if (entity.getBody().getWinner().equals("")) {
                    if (answerLayout.getQid() > 0) {//平局
                        ResultDialog.getInstance(MainActivity.this)
                                .showResult(getString(R.string.both_wrong), R.mipmap.tie_face);
                    } else {//对手未加入游戏
                        ResultDialog.getInstance(MainActivity.this)
                                .showResult(getString(R.string.other_not_join), 0);
                    }
                } else {//输了
                    ResultDialog.getInstance(MainActivity.this)
                            .showResult(getString(R.string.self_wrong), R.mipmap.fail_face);
                }
            }
            Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    finishActy(Constant.FINISH_NORMAL);
                }
            };
            handler.postDelayed(() -> handler.sendEmptyMessage(1), 2000);
        }

        /**
         * 答题正确
         */
        @Override
        public void answerRight() {
            mainPresenter.requestUseProp(answerLayout.getQid(), "0", 0);
        }

        /**
         * 答题倒计时结束
         */
        @Override
        public void answerCountdownOver() {
            LogUtils.e("答题倒计时结束：answerCountdownOver：" + answerLayout.isOtherIsUseYanshi());
            /**
             * 答题倒计时结束:
             * 1.正常十秒答题倒计时结束，
             * 2.延时的时间答题倒计时结束
             *如果是延时的倒计时结束，则不再执行otherUseYanshi
             * answerLayout.isOtherIsUseYanshi()：表示对方是否使用了延时卡，在10秒倒计时结束后，会执行otherUseYanshi
             * 如果是延时卡结束也会走这里，就需要判断是否是延时卡结束，如果是延时卡结束，则不能再执行otherUseYanshi了
             * 3.如果自己和对方都使用了延时卡，则不显示等待对方使用延时卡的界面
             */
            if (!answerLayout.isSelfIsUseYanshi()) {
                answerLayout.otherUseYanshi(Constant.YANSHI);
            }
        }

        /**
         * 显示延迟卡使用的提示
         */
        @Override
        public void showYanshiPopup() {
            if (yanshikaBean != null && yanshikaBean.getCount() > 0) {
                new BubblePopupWindow(MainActivity.this).showYanshiPopup(prop3);
            }
        }

        /**
         * 收到下发的用户信息和道具信息
         */
        @Override
        public void onReceiveUserProp(UserPropInfo user) {
            LogUtils.e("收到用户信息");
            userPropInfo = user;
            setViewData();
        }

        /**
         * 网络断开，退出游戏
         */
        @Override
        public void networkDis() {
            finishActy(Constant.FINISH_ACTIVE);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
//        LoadingDialog.getInstance(this).dismissDialog();
        ResultDialog.getInstance(this).closeResult();
        Process.killProcess(Process.myPid());
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            showBackDialog();
            return false;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }

    ///**
    // * 点击重连
    // */
    private void clickAgain() {
        idLoadingView.setVisibility(View.VISIBLE);
        llNetWrong.setVisibility(View.GONE);
        if (netIsWrong == 1) {
            mainPresenter.requestReadyGame();
        } else if (netIsWrong == 2) {
            //登录IM
            IMUtil.getInstance().init(this, loginListener);
            IMUtil.getInstance().login(Constant.IDENTIFIER, Constant.USERSIGN);
        } else if (netIsWrong == 3) {
            mainPresenter.requestStatGame();
        }
    }

    /**
     * 结束游戏调用
     * value=1表示主动退出
     * value=0表示正常结束游戏
     * value=2异常退出
     */
    private void finishActy(int value) {
        MediaUtil.getInstance(this).releaseMedia();
        IMUtil.getInstance().loginOut();
        answerLayout.stopCount();
        Intent intent = new Intent();
        intent.putExtra("error", value);
        intent.putExtra("roundId", Constant.GAME_ID);
        setResult(RESULT_OK, intent);
        finish();
    }

    /**
     * 弹出退出提示框
     */
    private void showBackDialog() {
        BackDialog.getInstance(MainActivity.this).setConfirmCallback(view1 -> {
            view1.dismiss();
            if (Constant.ROOMID.equals("") || Constant.ROOMID == null || Constant.OPENID == null
                    || Constant.OPENID.equals("")) {
                finishActy(Constant.FINISH_ACTIVE);
            } else {
                mainPresenter.requestQuitGame();
            }
        }).showDialog();
    }
}
